using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace watchman
{
    public partial class agent_system : Form
    {
        Graphics g;
        Pen pen;
        Rectangle[] rec;
        Rectangle[] place;

        int RobX, RobY;                             ///wsp. robota
        int dir;                                    ///Kierunek w którym porusza się obiekt, 4-Left, 6-Right, 8-Up, 2-Down, direction
        int way;                                    ///Czy jest droga
        bool wayLeft, wayRight, wayUp, wayDown;     ///W którym kierunku może się poruszać, do funkcji detectDirect()
        struct graph
        {
            public uint rX, rY;
            public bool wayLeft, wayRight, wayUp, wayDown;
            public int relation;
        };
        graph[][] Graph;

        public agent_system()
        {
            InitializeComponent();

            animation.Image = new Bitmap(600, 600);
            g = Graphics.FromImage(animation.Image);
            pen = new Pen(Color.Beige);

            Graph = new graph[17][];
            for (uint i = 0; i < Graph.Length; i++)
                Graph[i] = new graph[17];
            rec = new Rectangle[20];
            place = new Rectangle[20];
            RobX = 235;
            RobY = 65;
            dir = 4;
            way = 0;
            wayLeft = false; wayRight = false; wayUp = false; wayDown = false;

            InicializeGraphRelation();
            InicializeGraphDirect();
            InicializeGraphPosition();
        }

        private int RandomNumber(int max)
        {
            Random random = new Random();
            return random.Next(max);
        }

        private void InicializeGraphRelation()
        {
            /*i - po tym sprawdzamy
             * j - tutaj jest zapisana relacja*/
            for (uint i = 0; i < Graph.Length; i++)         //inicjalizacja początkowa
                for (uint j = 0; j < Graph.Length; j++)
                {
                    Graph[i][j].relation = -1;
                    Graph[i][j].wayDown = false;
                    Graph[i][j].wayLeft = false;
                    Graph[i][j].wayRight = false;
                    Graph[i][j].wayUp = false;
                }

            //relacje
            Graph[0][1].relation = 16;
            Graph[0][2].relation = 16;
            Graph[0][3].relation = 16;

            Graph[1][0].relation = 16;
            Graph[1][2].relation = 16;
            Graph[1][4].relation = 16;

            Graph[2][0].relation = 16;
            Graph[2][1].relation = 16;
            Graph[2][3].relation = 16;
            Graph[2][6].relation = 16;

            Graph[3][0].relation = 16;
            Graph[3][2].relation = 16;
            Graph[3][7].relation = 16;

            Graph[4][1].relation = 16;
            Graph[4][5].relation = 16;
            Graph[4][8].relation = 16;

            Graph[5][4].relation = 16;
            Graph[5][6].relation = 16;
            Graph[5][9].relation = 16;

            Graph[6][2].relation = 16;
            Graph[6][5].relation = 16;
            Graph[6][7].relation = 16;

            Graph[7][3].relation = 16;
            Graph[7][6].relation = 16;
            Graph[7][10].relation = 16;

            Graph[8][4].relation = 16;
            Graph[8][9].relation = 16;
            Graph[8][11].relation = 16;

            Graph[9][5].relation = 16;
            Graph[9][8].relation = 16;
            Graph[9][10].relation = 16;
            Graph[9][13].relation = 16;

            Graph[10][9].relation = 16;
            Graph[10][7].relation = 16;
            Graph[10][15].relation = 16;

            Graph[11][8].relation = 16;
            Graph[11][12].relation = 16;
            Graph[11][14].relation = 16;

            Graph[12][11].relation = 16;
            Graph[12][14].relation = 16;
            Graph[12][15].relation = 16;

            Graph[13][9].relation = 16;
            Graph[13][12].relation = 16;
            Graph[13][15].relation = 16;

            Graph[14][11].relation = 16;
            Graph[14][12].relation = 16;
            Graph[14][15].relation = 16;

            Graph[15][13].relation = 16;
            Graph[15][14].relation = 16;
            Graph[15][10].relation = 16;

        }

        private void InicializeGraphDirect()
        {
            /*i - po tym sprawdzamy
             * j - tutaj jest zapisana relacja*/

            //kierunki
            Graph[0][0].wayDown = true;
            Graph[0][0].wayLeft = true;
            Graph[0][0].wayRight = true;

            Graph[1][1].wayDown = true;
            Graph[1][1].wayUp = true;
            Graph[1][1].wayRight = true;

            Graph[2][2].wayDown = true;
            Graph[2][2].wayUp = true;
            Graph[2][2].wayLeft = true;
            Graph[2][2].wayRight = true;

            Graph[3][3].wayUp = true;
            Graph[3][3].wayLeft = true;
            Graph[3][3].wayRight = true;

            Graph[4][4].wayDown = true;
            Graph[4][4].wayUp = true;
            Graph[4][4].wayRight = true;

            Graph[5][5].wayDown = true;
            Graph[5][5].wayUp = true;
            Graph[5][5].wayRight = true;

            Graph[6][6].wayUp = true;
            Graph[6][6].wayLeft = true;
            Graph[6][6].wayRight = true;

            Graph[7][7].wayDown = true;
            Graph[7][7].wayUp = true;
            Graph[7][7].wayLeft = true;

            Graph[8][8].wayUp = true;
            Graph[8][8].wayLeft = true;
            Graph[8][8].wayRight = true;

            Graph[9][9].wayDown = true;
            Graph[9][9].wayUp = true;
            Graph[9][9].wayLeft = true;
            Graph[9][9].wayRight = true;

            Graph[10][10].wayDown = true;
            Graph[10][10].wayLeft = true;
            Graph[10][10].wayRight = true;

            Graph[11][11].wayDown = true;
            Graph[11][11].wayUp = true;
            Graph[11][11].wayRight = true;

            Graph[12][12].wayDown = true;
            Graph[12][12].wayLeft = true;
            Graph[12][12].wayRight = true;

            Graph[13][13].wayDown = true;
            Graph[13][13].wayUp = true;
            Graph[13][13].wayLeft = true;

            Graph[14][14].wayDown = true;
            Graph[14][14].wayUp = true;
            Graph[14][14].wayRight = true;

            Graph[15][15].wayUp = true;
            Graph[15][15].wayLeft = true;
            Graph[15][15].wayRight = true;

        }

        private void InicializeGraphPosition()
        {
            Graph[0][0].rX = 400;
            Graph[1][1].rX = 200;
            Graph[2][2].rX = 400;
            Graph[3][3].rX = 500;
            Graph[4][4].rX = 200;
            Graph[5][5].rX = 320;
            Graph[6][6].rX = 400;
            Graph[7][7].rX = 560;
            Graph[8][8].rX = 200;
            Graph[9][9].rX = 320;
            Graph[10][10].rX = 460;
            Graph[11][11].rX = 120;
            Graph[12][12].rX = 220;
            Graph[13][13].rX = 320;
            Graph[14][14].rX = 220;
            Graph[15][15].rX = 320;

            Graph[0][0].rY = 60;
            Graph[1][1].rY = 120;
            Graph[2][2].rY = 120;
            Graph[3][3].rY = 120;
            Graph[4][4].rY = 220;
            Graph[5][5].rY = 260;
            Graph[6][6].rY = 260;
            Graph[7][7].rY = 260;
            Graph[8][8].rY = 320;
            Graph[9][9].rY = 320;
            Graph[10][10].rY = 320;
            Graph[11][11].rY = 400;
            Graph[12][12].rY = 400;
            Graph[13][13].rY = 400;
            Graph[14][14].rY = 500;
            Graph[15][15].rY = 500;
        }

        private void rectangleLoad()
        {
            //rec[0] = new Rectangle(40, 120, 20, 120); //to do wywalenia
            //rec[1] = new Rectangle(40, 40, 120, 20);
            //rec[2] = new Rectangle(140, 40, 20, 100);
            rec[3] = new Rectangle(200, 120, 360, 20);
            rec[4] = new Rectangle(200, 60, 20, 280);
            rec[5] = new Rectangle(200, 60, 320, 20);
            rec[6] = new Rectangle(400, 60, 20, 220);
            rec[7] = new Rectangle(500, 60, 20, 80);
            rec[8] = new Rectangle(560, 120, 20, 220);
            rec[9] = new Rectangle(200, 220, 140, 20);
            rec[10] = new Rectangle(320, 220, 20, 300);
            rec[11] = new Rectangle(320, 260, 260, 20);
            rec[12] = new Rectangle(120, 320, 460, 20);
            rec[13] = new Rectangle(120, 320, 20, 260);
            rec[14] = new Rectangle(120, 400, 220, 20);
            rec[15] = new Rectangle(220, 500, 260, 20);
            rec[16] = new Rectangle(120, 560, 120, 20);
            rec[17] = new Rectangle(220, 400, 20, 180);
            rec[18] = new Rectangle(460, 320, 20, 200);
            rec[19] = new Rectangle(220, 500, 260, 20);

            place[0] = new Rectangle(400, 60, 20, 20);
            place[1] = new Rectangle(400, 120, 20, 20);
            place[2] = new Rectangle(500, 120, 20, 20);
            place[3] = new Rectangle(320, 260, 20, 20);
            place[4] = new Rectangle(200, 220, 20, 20);
            place[5] = new Rectangle(200, 320, 20, 20);
            place[6] = new Rectangle(320, 320, 20, 20);
            place[7] = new Rectangle(400, 260, 20, 20);
            place[8] = new Rectangle(200, 120, 20, 20);
            place[9] = new Rectangle(560, 260, 20, 20);
            place[10] = new Rectangle(460, 320, 20, 20);
            place[11] = new Rectangle(120, 400, 20, 20);
            place[12] = new Rectangle(220, 400, 20, 20);
            place[13] = new Rectangle(320, 400, 20, 20);
            place[14] = new Rectangle(220, 500, 20, 20);
            place[15] = new Rectangle(320, 500, 20, 20);
            //place[16] = new Rectangle(40, 120, 20, 20);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            rectangleLoad();
            for (int i = 0; i < 20; i++)
                g.FillRectangle(new SolidBrush(Color.DarkOrange), rec[i]);


            animation.Refresh();

            timer1.Interval -= 90;
        }

        private void DirectionDetect()
        {

            if (dir == 4)
            {
                if ((animation.Image as Bitmap).GetPixel((RobX - 6), RobY).ToArgb() == Color.GreenYellow.ToArgb())   //sprawdzamy czy koniec drogi
                {
                    if ((animation.Image as Bitmap).GetPixel(RobX, RobY - 6).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayUp = true;
                    }
                    if ((animation.Image as Bitmap).GetPixel(RobX, RobY + 16).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayDown = true;
                    }
                    if (way == 1 || way == 2)
                    {
                        if (wayUp) dir = 8;
                        else dir = 2;
                    }

                    way = 0;
                    wayDown = false;
                    wayUp = false;
                }
                else
                {
                    RobX--;
                }
            }
            else if (dir == 6)
            {
                if ((animation.Image as Bitmap).GetPixel((RobX + 16), RobY).ToArgb() == Color.GreenYellow.ToArgb())   //sprawdzamy czy koniec drogi
                {
                    //sprawdzamy gdzie jest droga, jak jest tylko w jednym kierunku
                    if ((animation.Image as Bitmap).GetPixel(RobX, RobY - 6).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayUp = true;
                    }
                    if ((animation.Image as Bitmap).GetPixel(RobX, RobY + 16).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayDown = true;
                    }
                    if (way == 1 || way == 2)
                    {
                        if (wayUp) dir = 8;
                        else dir = 2;
                    }

                    way = 0;
                    wayDown = false;
                    wayUp = false;
                }
                else//add
                {
                    RobX++;
                }
            }
            else if (dir == 8)
            {
                if ((animation.Image as Bitmap).GetPixel(RobX, RobY - 6).ToArgb() == Color.GreenYellow.ToArgb())
                {
                    //sprawdzamy gdzie jest droga, jak jest tylko w jednym kierunku
                    if ((animation.Image as Bitmap).GetPixel(RobX + 16, RobY).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayRight = true;
                    }
                    if ((animation.Image as Bitmap).GetPixel(RobX - 6, RobY).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayLeft = true;
                    }
                    if (way == 1 || way == 2)
                    {
                        if (wayRight) dir = 6;
                        else dir = 4;
                    }

                    way = 0;
                    wayLeft = false;
                    wayRight = false;
                }
                else
                {
                    RobY--;
                }
            }
            else if (dir == 2)
            {
                if ((animation.Image as Bitmap).GetPixel(RobX, RobY + 15).ToArgb() == Color.GreenYellow.ToArgb())
                {
                    //sprawdzamy gdzie jest droga, jak jest tylko w jednym kierunku
                    if ((animation.Image as Bitmap).GetPixel(RobX + 15, RobY).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayRight = true;
                    }
                    if ((animation.Image as Bitmap).GetPixel(RobX - 6, RobY).ToArgb() != Color.GreenYellow.ToArgb())
                    {
                        way++;
                        wayLeft = true;
                    }
                    if (way == 1 || way == 2)
                    {
                        if (wayRight) dir = 6;
                        else dir = 4;
                    }


                    way = 0;
                    wayLeft = false;
                    wayRight = false;
                }
                else
                {
                    RobY++;     ///Nie wiem czy dobrze zrobiłem że tu usunąłem else
                }
            }
        }

        private void IntersectionDetect()
        {
            if (dir == 6)
            {
                if ((animation.Image as Bitmap).GetPixel(RobX + 14, RobY).ToArgb() == Color.DarkOrange.ToArgb() &&
                    (animation.Image as Bitmap).GetPixel(RobX + 13, RobY).ToArgb() == Color.Yellow.ToArgb())   ///sprawdzamy czy skrzyżowanie
                {
                    RobX--;
                    for (uint i = 0; i < Graph.Length; i++)
                    {
                        if ((Graph[i][i].rX + 5) == RobX && (Graph[i][i].rY + 5) == RobY) ///Sprawdzamy czy jest w wierzchołku (kwadracie), sprawdza graf
                        {
                            int rand = RandomNumber(100);
                            ///Wybieramy nowy kierunke losowo z możliwych
                            if (Graph[i][i].wayDown && rand % 3 == 0) { dir = 2; RobY += 2; }
                            else if (Graph[i][i].wayUp && rand % 3 == 1) { dir = 8; RobY -= 2; }
                            else if (Graph[i][i].wayRight && rand % 3 == 2) { dir = 6; RobX += 2; }
                            //else if (Graph[i][i].wayLeft && rand % 4 == 3) dir = 4;
                            else if (Graph[i][i].wayDown) { dir = 2; RobX += 2; }
                            else if (Graph[i][i].wayUp) { dir = 8; RobY -= 2; }

                            Graph[i][i].relation += 2; //albo +=3
                            break;
                        }
                    }
                    // if(dir==2) RobY++;

                }
            }
            else if (dir == 4)
            {
                if ((animation.Image as Bitmap).GetPixel(RobX - 5, RobY).ToArgb() != Color.Yellow.ToArgb() &&
                    (animation.Image as Bitmap).GetPixel(RobX - 4, RobY).ToArgb() == Color.Yellow.ToArgb())   //sprawdzamy czy skrzyżowanie
                {
                    RobX++;
                    ///??
                    for (uint i = 0; i < Graph.Length; i++)
                    {
                        if ((Graph[i][i].rX + 5) == RobX && (Graph[i][i].rY + 5) == RobY)
                        {
                            ///Wybieramy nowy kierunke losowo z możliwych
                            if (Graph[i][i].wayDown && RandomNumber(100) % 3 == 0) { dir = 2; RobY += 2; }
                            else if (Graph[i][i].wayUp && RandomNumber(100) % 3 == 1) { dir = 8; RobY -= 2; }
                            //else if (Graph[i][i].wayRight && RandomNumber(100) % 4 == 2) dir = 6;
                            else if (Graph[i][i].wayLeft && RandomNumber(100) % 3 == 2) { dir = 4; RobX -= 2; }
                            else if (Graph[i][i].wayDown) { dir = 2; RobY += 2; }
                            else if (Graph[i][i].wayUp) { dir = 8; RobY -= 2; }


                            Graph[i][i].relation += 2; //albo +=3
                            break;
                        }
                        else
                        {
                            dir = 6;
                        }
                    }
                }
            }
            else if (dir == 2)
            {
                if (((animation.Image as Bitmap).GetPixel(RobX, RobY + 14).ToArgb() == Color.DarkOrange.ToArgb() ||
                    (animation.Image as Bitmap).GetPixel(RobX, RobY + 14).ToArgb() == Color.GreenYellow.ToArgb()) &&
                    (animation.Image as Bitmap).GetPixel(RobX, RobY + 13).ToArgb() == Color.Yellow.ToArgb())   //sprawdzamy czy skrzyżowanie
                {
                    RobY--;
                    ///??
                    for (uint i = 0; i < Graph.Length; i++)
                    {
                        if ((Graph[i][i].rX + 5) == RobX && (Graph[i][i].rY + 5) == RobY)
                        {
                            ///Wybieramy nowy kierunke losowo z możliwych
                            //if (Graph[i][i].wayUp && RandomNumber(100) % 3 == 0) dir = 8;
                            if (Graph[i][i].wayDown && RandomNumber(100) % 3 == 0) { dir = 2; RobY += 2; }
                            else if (Graph[i][i].wayRight && RandomNumber(100) % 3 == 1) { dir = 6; RobX += 2; }
                            else if (Graph[i][i].wayLeft && RandomNumber(100) % 3 == 2) { dir = 4; RobX -= 2; }
                            else if (Graph[i][i].wayRight) { dir = 6; RobX -= 2; }
                            else if (Graph[i][i].wayLeft) { dir = 4; RobX += 2; }


                            Graph[i][i].relation += 3; //albo +=2
                            break;
                        }
                        else
                        {
                            dir = 6;
                        }
                    }
                }
            }
            else if (dir == 8)
            {
                if ((animation.Image as Bitmap).GetPixel(RobX, RobY - 5).ToArgb() != Color.Yellow.ToArgb() &&
                    (animation.Image as Bitmap).GetPixel(RobX, RobY - 4).ToArgb() == Color.Yellow.ToArgb())   //sprawdzamy czy skrzyżowanie
                {
                    ///??
                    for (uint i = 0; i < Graph.Length; i++)
                    {
                        if ((Graph[i][i].rX + 5) == RobX && (Graph[i][i].rY + 5) == RobY)
                        {
                            ///Wybieramy nowy kierunke losowo z możliwych
                            //if (Graph[i][i].wayDown && RandomNumber(100) % 4 == 0) dir = 2;
                            if (Graph[i][i].wayUp && RandomNumber(100) % 3 == 0) { dir = 8; RobY -= 2; }
                            else if (Graph[i][i].wayRight && RandomNumber(100) % 3 == 1) { dir = 6; RobX += 2; }
                            else if (Graph[i][i].wayLeft && RandomNumber(100) % 3 == 2) { dir = 4; RobX -= 2; }
                            else if (Graph[i][i].wayLeft) { dir = 4; RobX -= 2; }
                            else if (Graph[i][i].wayRight) { dir = 6; RobX += 2; }


                            Graph[i][i].relation += 2; //albo +=3
                            break;
                        }
                        else
                        {
                            dir = 2;
                        }
                    }
                }
            }

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            g.Clear(Color.GreenYellow);

            for (int i = 0; i < 20; i++)
                g.FillRectangle(new SolidBrush(Color.DarkOrange), rec[i]);
            for (int i = 0; i < 17; i++)
                g.FillRectangle(new SolidBrush(Color.Yellow), place[i]);
            g.FillRectangle(new SolidBrush(Color.DarkTurquoise), RobX, RobY, 10, 10);

            animation.Refresh();

            DirectionDetect();
            IntersectionDetect();
        }

        private void run_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void stop_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }
    }
}
